
import { intl } from '@/utils';
import DataSource from 'devextreme/data/data_source';
import type { DataGridCell } from 'devextreme/excel_exporter';
import { formatNumber } from 'devextreme/localization';
import { Guid } from 'guid-factory/lib/Guid';
import { nanoid } from 'nanoid';
import queryString from 'query-string';
import type { Ref } from 'react';
import { msgError, msgInfo } from './msg';

/**
 * 是否是数字
 * @param str
 * @returns
 */
export function isNumeric(str: any) {
  return !isNaN(str) /*  && !isNaN(parseFloat(str)) */;
}

/**
 * tabBox组件下载渲染样式(字符数据方式)
 * 注意属性设置 maxDisplayedTags: 1,
 */
export function tabBoxOnMultiTagPreparingOfStrArray(args: any) {
  const selectedItemsLength = args.selectedItems.length;
  if (selectedItemsLength > 0) {
    if (typeof args.selectedItems[0] && args.selectedItems[0].hasOwnProperty('id')) {
      ///如果是对象排序
      args.selectedItems.sort((a: any, b: any) => a.id.localeCompare(b.id));
    }
    let value: any = args.selectedItems[0];
    if (typeof value === 'object') {
      if (value.text) {
        //如果是对象
        value = value.text;
      } else if (value.name) {
        //如果是对象
        value = value.name;
      }
    }
    args.text = `${value} 等${selectedItemsLength}项`;
  } else {
    args.cancel = true;
  }
}

/**
 * tabBox组件下载渲染样式(属性方式)
 * 注意属性设置 maxDisplayedTags: 1,
 */
export function tabBoxOnMultiTagPreparingOfProp(args: any, propName: string) {
  const selectedItemsLength = args.selectedItems.length;
  if (selectedItemsLength > 0) {
    const value = args.selectedItems[0][propName];
    args.text = `${value} 等${selectedItemsLength}项`;
  } else {
    args.cancel = true;
  }
}

//可编辑的列
export function canEditHeaderCellTemplate(cellElement: HTMLElement, cellData: any) {
  const text = cellData.column.caption;
  cellElement.innerHTML =
    `<span title="${text} ` +
    intl('pub.thisColCanEdit', '此列可编辑') +
    `" style="color:var(--cpasPrimaryColor);">${text}</span>`;
}
//可编辑的列
export function longTitileHeaderCellTemplate(caption: string, headerHint: string) {
  return function longTitileHeaderCellTemplate_inner(cellElement: HTMLElement, cellData: any) {
    //  let text = cellData.column.caption;
    debugger;
    cellElement.innerHTML =
      `<span title="${headerHint} ` + +`" style="color:var(--cpasPrimaryColor);">${caption}</span>`;
  };
}

/**
 * 获取缩放比例,程序设计按1366来设计
 * @returns
 */
export function getWindowZoomRate() {
  return window.innerWidth / 1366;
}
/**
 * 获取缩放比例后的实际宽度
 */
export function getZoomScale(value: number) {
  return value * getWindowZoomRate();
}
/**
 * yyyy-MM-dd
 * @param date
 * @returns
 */
export function formatDate(date: Date) {
  const year = date.getFullYear();
  const month = (date.getMonth() + 1).toString().padStart(2, '0');
  const day = date.getDate().toString().padStart(2, '0');
  return `${year}-${month}-${day}`;
}
export function formatDateYYMMDD(date: Date) {
  const year = date.getFullYear();
  const month = (date.getMonth() + 1).toString().padStart(2, '0');
  const day = date.getDate().toString().padStart(2, '0');
  return `${year}${month}${day}`;
}
/**
 * 格式化日期 2023-06-03 09:30:20
 * @param date
 * @returns
 */
export function formatDateTime(date: Date) {
  const dateInfo = getDateInfo(date);
  return (
    dateInfo.year +
    '-' +
    dateInfo.month +
    '-' +
    dateInfo.day +
    ' ' +
    dateInfo.hour +
    ':' +
    dateInfo.minute +
    ':' +
    dateInfo.second
  );
}
export function formatDateTimeForZcbfid() {
  const dateInfo = getDateInfo(new Date());
  return dateInfo.hour + dateInfo.minute + dateInfo.second + dateInfo.milliseconds;
}
/**
 * 格式化到文件名
 * @param date
 */
export function formatDateTimeForFileName(date: Date) {
  const dateInfo = getDateInfo(date);
  return (
    dateInfo.year +
    dateInfo.month +
    dateInfo.day +
    '_' +
    dateInfo.hour +
    dateInfo.minute +
    dateInfo.second +
    '.' +
    dateInfo.milliseconds
  );
}

export function formatDateTimeForTableName(date: Date) {
  const dateInfo = getDateInfo(date);
  return (
    dateInfo.year +
    dateInfo.month +
    dateInfo.day +
    '_' +
    dateInfo.hour +
    dateInfo.minute +
    dateInfo.second
  );
}
/**
 * 格式化到文件名
 * @param date
 */
export function formatDateTimeLocalFile(date: Date) {
  const dateInfo = getDateInfo(date);
  return dateInfo.year + dateInfo.month + dateInfo.day + '_' + dateInfo.hour + dateInfo.minute + dateInfo.second;
}
/**
 * 获取日期信息
 * @param date
 * @returns
 */
export function getDateInfo(date: Date) {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  const hour = String(date.getHours()).padStart(2, '0');
  const minute = String(date.getMinutes()).padStart(2, '0');
  const second = String(date.getSeconds()).padStart(2, '0');
  const milliseconds = String(date.getMilliseconds()).padStart(3, '0');
  return { year, month, day, hour, minute, second, milliseconds };
}

/**
 *
 * @param excelDate 把数据转换为格式化后的日期 yyyy-MM-dd
 * @returns
 */
export function excelDateToJSDate(excelDate: number) {
  const days = excelDate - 25569; // 先减掉“整数部分”代表的天数
  const seconds = days * 86400; // 将剩余的天数转换为秒数
  const jsDate = new Date(seconds * 1000); // 将秒数转换为毫秒数，并生成Date对象

  const year = jsDate.getFullYear();
  const month = (jsDate.getMonth() + 1).toString().padStart(2, '0');
  const day = jsDate.getDate().toString().padStart(2, '0');

  return `${year}-${month}-${day}`;
}

/**
 * 获取一个短的随机字符串
 * @returns
 */
export function getShortUniqueId(): string {
  const timestamp: number = new Date().getTime(); // 获取当前时间戳
  const randomChars: string = Math.random().toString(36).substring(2, 5); // 生成随机字符串
  return timestamp.toString(16) + randomChars; // 拼接并返回唯一ID
}
//加表格线并设置为18px高
export function addTableLineToSheet(worksheet: any) {
  worksheet.eachRow(function (row: any, rowNumber: number) {
    row.height = 18 / 0.75;
    for (let col = 1; col <= row.cellCount; col++) {
      const cell = row.getCell(col);
      cell.border = {
        top: { style: 'thin' },
        left: { style: 'thin' },
        bottom: { style: 'thin' },
        right: { style: 'thin' },
      };
    }
  });
}
/**
 * 删除文本中序号,如 1.abc  2.dbc   或 1、2、
 * @param value
 */
export function getDecNoOfStr(value: string) {
  //把字段前面加序号..
  // let value: string = itemData.displayName || '';
  let pos = value.indexOf('.');
  if (pos < 0 || pos > 3) {
    pos = value.indexOf('、');
  }
  if (pos > -1 && pos < 3) {
    value = value.substring(pos + 1);
  }
  return value;
}
/**
 * 获取带序号的列标题
 * @param itemIndex
 * @param displayName
 * @returns
 */
export function getJeColumnCaptionOfNo(itemIndex: number, displayName?: string) {
  return itemIndex + 1 + '、' + getDecNoOfStr(displayName || '');
}

//高量关键字
export const highlightSearchTerm = (text: string, subText: string) => {
  if (!subText) return text;
  const regex = new RegExp(subText, 'gi');
  return text.replace(regex, (match: any) => `<mark class='search-mark'>${match}</mark>`);
};
/**
 * 同时高亮每一个字
 * @param text
 * @param subText
 * @returns
 */
export const highlightSearchTermAll = (text: string, subText?: string) => {
  if (!subText || !text) return text;
  const keywords = subText.split('');
  // 遍历关键字数组并逐个高亮
  keywords.forEach((keyword) => {
    text = highlightSearchTerm(text, keyword);
  });
  return text;
};

/**
 * 获取高亮的数据表表
 * @param dataArray
 * @param fieldName
 * @param subStr
 * @returns
 */
export function getHighlightDataList(dataArray: any[], fieldName: string, subStr: string): any[] {
  for (const i in dataArray) {
    if (Object.prototype.hasOwnProperty.call(dataArray, i)) {
      const element = dataArray[i];
      element.displayText = highlightSearchTerm(element[fieldName], subStr);
    }
  }
  return dataArray;
}

/**
 * 获取一个
 * @param formItems
 * @param dataField
 * @returns
 */
export function getFormItem(formItems: any[], dataField: string) {
  for (const i in formItems) {
    if (Object.prototype.hasOwnProperty.call(formItems, i)) {
      const formItem = formItems[i];
      if (formItem.items) {
        for (const j in formItem.items) {
          if (Object.prototype.hasOwnProperty.call(formItem.items, j)) {
            if (formItem.items[j].dataField == dataField) {
              return formItem.items[j];
            }
          }
        }
      }
    }
  }
  return null;
}
/**
 * 获取编辑属性
 * @returns
 */

export function getFormItemEditorOption(formItems: any[], dataField: string) {
  const formItem = getFormItem(formItems, dataField);
  return formItem ? formItem.editorOptions : undefined;
}
/**
 *
 * @param formRef
 * @param dataField
 * @param prop
 * @returns
 */
export function getFormItemEditorOptionValue(formItems: any[], dataField: string, prop: string) {
  const formItem = getFormItem(formItems, dataField);
  return formItem ? formItem.editorOptions[prop] : undefined;
}
/**
 *
 * @param formRef
 * @param dataField
 * @param prop
 * @returns
 */
export function setFormItemEditorOptionValue(formItems: any[], dataField: string, prop: string, value: any) {
  const formItem = getFormItem(formItems, dataField);
  if (formItem && formItem.editorOptions) {
    const editorOptions: any = formItem.editorOptions;
    editorOptions[prop] = value;
  }
}
/**
 * 设置选项值
 * @param formItems
 * @param dataField
 * @param prop
 * @param value
 */
export function setFormItemOptionValue(formItems: any[], dataField: string, prop: string, value: any) {
  const formItem = getFormItem(formItems, dataField);
  if (formItem) {
    formItem[prop] = value;
  }
}
/**
 * 判断是否JSON
 * @param str
 * @returns
 */
export function isJSONStr(str: string) {
  if (!str) return false;
  try {
    JSON.parse(str);
    return true;
  } catch (error) {
    return false;
  }
}
/**
 * 获取全名
 * @param userCode
 * @param trueName
 * @returns
 */
export function getFullUserName(userCode: string, trueName: string) {
  return `【${userCode}】${trueName}`;
}

//转为整数
export function getInt(value: number) {
  return value.toFixed(0);
}
/**
 * 获取文件大小的显示
 * @param value
 * @returns
 */
export function getFileSizeDisplay(value: number) {
  let unit = 'B';
  if (value > 1024) {
    unit = 'KB';
    value = value / 1024;
  }
  if (value > 1024) {
    unit = 'MB';
    value = value / 1024;
  }
  if (value > 1024) {
    unit = 'GB';
    value = value / 1024;
  }
  if (value > 1024) {
    unit = 'TB';
    value = value / 1024;
  }
  return {
    value: value,
    unit,
    display: value.toFixed(1) + ' ' + unit,
  };
}
//获取文件大小的显示
export function getFileSizeDisplayText(value: number) {
  return getFileSizeDisplay(value).display;
}
/**
 * 用window来存储临时变量,获取值
 * @param name
 * @returns
 */
export function getTempVar(name: string) {
  return window['tempVar' + name];
}
/**
 * 用window来存储临时变量,设置值
 * @param name
 * @param value
 * @returns
 */
export function setTempVar(name: string, value: any) {
  return (window['tempVar' + name] = value);
}
/**
 * 用window来存储临时变量,删除
 * @param name
 */
export function delTempVar(name: string) {
  delete window['tempVar' + name];
}
/**
 * 延时删除
 * @param name
 * @param ms
 */
export function delTempVarDelay(name: string, ms?: number) {
  setTimeout(() => {
    delete window['tempVar' + name];
  }, ms || 1000);
}

/**
 * 获取json第一个值
 * @param obj
 * @returns
 */
export function getObjectFirstValue(obj: object) {
  const keys = Object.keys(obj);
  return keys.length > 0 ? obj[keys[0]] : undefined;
}
/**
 * //打开一个url并且最大化
 * @param url
 * @param title
 */
export function openUrlByNewWindowMax(url: string, title?: string) {
  const mainObject = window.main.mainObject;
  if (mainObject.openUrlByNewWindowMax) {
    mainObject.openUrlByNewWindowMax(url, title);
  } else {
    window.open(url, '_blank');
  }
}

//获取分组数据源
export function getGroupedDataSource(ungroupedData: any[], key: string, groupBy: string) {
  if (!ungroupedData || ungroupedData.length == 0) return ungroupedData;
  const fromUngroupedData = new DataSource({
    store: {
      type: 'array',
      data: ungroupedData,
      key: key,
    },
    group: groupBy,
  });
  return fromUngroupedData;
}

/**
 * 删除路径不认的字符
 * @param value
 * @returns
 */
export function replaceInvalidChar(value: string): string {
  let str = value.replaceAll('\r', '');
  str = str.replaceAll('\t', '');
  str = str.replaceAll('\b', '');
  str = str.replaceAll('\\', '');
  str = str.replaceAll('/', '');
  str = str.replaceAll(':', '');
  str = str.replaceAll('*', '');
  str = str.replaceAll('?', '');
  str = str.replaceAll('<', '');
  str = str.replaceAll('>', '');
  str = str.replaceAll('|', '');
  str = str.replaceAll('\n', '');
  return str;
}

export function replaceInvalidFileName(value: string): string {
  let str = replaceInvalidChar(value)
  str = str.replaceAll('[', '【');
  str = str.replaceAll(']', '】');
  return str;
}
/**
 * 是否隐藏头
 * @returns
 */
export function getIsHideHeader() {
  let isHideHeader = (localStorage.getItem('curCpasApp.url') ?? '').includes('hideHeader=1');
  if (!isHideHeader) {
    isHideHeader = (window.location.href ?? '').includes('hideHeader=1');
  }
  return isHideHeader;
}
/**
 * 检查是否是作为微应用存在
 * @returns
 */
export function getIsMicroPage() {
  let isMicroApp = (localStorage.getItem('curCpasApp.url') ?? '').includes('isMicroPage=1');
  if (!isMicroApp) {
    isMicroApp = (window.location.href ?? '').includes('isMicroPage=1');
  }
  return isMicroApp;
}
/**
 * * 是否是有效的url
 * @param url
 * @returns
 */
export function isValidURL(url: string) {
  const pattern = /^https?:\/\/[^\s/$.?#].[^\s]*$/;
  return pattern.test(url);
}
/**
 * 添加URL参数
 * @param url
 * @param params
 * @returns
 */
export function addUrlParam(url: string, params = {}) {
  // const parsedUrl = queryString.parseUrl(url, {parseFragmentIdentifier: true});
  const index = url.indexOf('?');
  const origin = index >= 0 ? url.slice(0, index) : url;
  const search = index >= 0 ? url.slice(index + 1) : '';
  const parsedParams = queryString.parse(search);
  const mergedParams = { ...parsedParams, ...params };
  const queryStringParams = queryString.stringify(mergedParams);
  return `${origin}?${queryStringParams}`;
}

/**
 *
 * @param path 组件的path路径或者完整路径
 * @returns 拼接location.origin返回hash的完整路径，history路径请传递完整路径
 */
export function createMicroPageUrl(path: string) {
  if (isValidURL(path)) {
    return addUrlParam(path, {
      isMicroPage: '1',
      hideHeader: '1', //隐藏表头
      position: 'childWindow', //在子窗口中
    });
  } else {
    //window.location.pathname要加入才能完整
    const createUrl = window.location.origin + window.location.pathname + '#' + path;
    if (isValidURL(createUrl)) {
      return isValidURL(createUrl)
        ? addUrlParam(createUrl, {
          isMicroPage: '1',
          hideHeader: '1', //隐藏表头
          position: 'childWindow',
        })
        : '';
    } else {
      return path;
    }
  }
}
export function getGuid() {
  return Guid.newGuid().replaceAll('-', '').toUpperCase();
}
export function openFileByFileName(fileName: string) {
  const mainObject = window.main.mainObject;
  if (!mainObject.fileExists(fileName)) {
    msgError(intl('ac.fileNotExists', '文件不存在') + ':\n' + fileName);
    return;
  }
  msgInfo(intl('cs.fileOpening', '文件正在打开,请稍候...'), 2000);
  mainObject.openFile(fileName);
}

export function setDevOptions(devRef: Ref<any>, values: object) {
  if (devRef && devRef.current && devRef.current.instance) {
    devRef.current.instance.option(values);
    //在上面的示例中，我们在GridRef上调用instance方法来获取Grid的实例。然后，我们使用option方法更改Grid的columns属性，
    //并在更改后调用repaint()或resize()方法，以便应用新配置并刷新Grid。
    devRef.current.instance.repaint(); //重绘表格 20230304
  }
}
/**
 * 获取属性
 * @param devRef
 * @param optionName
 * @param value
 */

export function getDevOption(devRef: Ref<any>, optionName: string) {
  if (devRef && devRef.current && devRef.current.instance) {
    return devRef.current.instance.option(optionName);
  }
  return null;
}

//普通label 14号字
export function getLabelHtmlStatic14Size(text: string) {
  return ` <span style='font-size:14px;'    title='${text}' >${text}</span>`;
}

//获取分页的默认属性

export function getGridDefaultPageProps(): any {
  return {
    visible: true,
    showPageSizeSelector: true,
    showNavigationButtons: true,
    showInfo: true,
    displayMode: 'full',//full/compact
    allowedPageSizes: [10, 20, 30, 40, 50, 100, 200, 500, 1000],//1万的去掉太慢
  };
}

/**
 * 输出Excel时自定义的内容字段
 * @param options
 */
export function acGridExportCustomizeCell(options: { gridCell?: DataGridCell; excelCell?: any }) {
  if (options.gridCell?.rowType == 'data') {
    //画数据地
    if (options.gridCell.column?.format == consts.JeFormat) {
      //金额格式化 getFieldIsReplyJeField(dataField)
      options.excelCell.value = formatNumber(options.gridCell.value, consts.JeFormat);
    }
  }
}

//可编辑的列  多行表头 表头换行,通过 <br> 等html标记来换行
export function canMultiLineEditHeaderCellTemplate(cellElement: HTMLElement, cellData: any) {
  const text = cellData.column.caption;
  cellElement.innerHTML =
    `<span class='multiLine-header'  title="${text} ` +
    intl('pub.thisColCanEdit', '此列可编辑') +
    `" style="color:var(--cpasPrimaryColor);">${text}</span>`;
}
/**
 * 多行表头 表头换行,通过 <br> 等html标记来换行
 * @param cellElement
 * @param cellData
 */
export function getMultiLineHeaderCellTemplate(cellElement: HTMLElement, cellData: any) {
  cellElement.innerHTML = `<span class='multiLine-header'> ${cellData.column.caption}</span>`;
}

/**
 * 更新报表模板api的熟悉
 */
export function updateReportTemplateProps(res: any) {
  if (res.data) {
    const { originGroupPart } = JSON.parse(window.sessionStorage.electronParams)?.params;
    if (originGroupPart) {
      res.data.AuditReportTemplate = originGroupPart.auditReportTemplate;
      res.data.TXName = originGroupPart.txName;
    }
  }
}
//报表的高度
export function getReportHeight() {
  return window.innerHeight - 160;
}
/**
 * ts中 ,有一个树结构的数组,guid是关键字,parentId是父id,我把通过一个guid的值,找出有所有子孙的个数
 * @param treeData
 * @param nodeId
 * @returns
 */
export function countDescendants(treeData: any[], nodeId: string): number {
  const children = treeData.filter((node) => node.parentId === nodeId && node.isMerge == 1);
  let count = children.length;

  for (const child of children) {
    count += countDescendants(treeData, child.guid);
  }

  return count;
}
/**
 *
如果你想从指定的节点开始找出所有末级节点，你可以稍微修改上面的代码。以下是一个示例函数，它会从指定节点开始找出所有末级节点：
 
 * @param tree [{guid,parentId,...}]
 * @returns
 */
export function findLeafNodesFromNode(tree: any[], startNodeGuid?: string): any[] {
  const leafNodes: any[] = [];
  const visitedNodes: Set<string> = new Set();

  function dfs(nodeGuid: string) {
    visitedNodes.add(nodeGuid);

    const children = tree.filter((node) => node.parentId === nodeGuid && node.isMerge == 1);

    if (children.length === 0) {
      leafNodes.push(tree.find((node) => node.guid === nodeGuid && node.isMerge == 1)!);
    } else {
      for (const child of children) {
        if (!visitedNodes.has(child.guid)) {
          dfs(child.guid);
        }
      }
    }
  }

  dfs(startNodeGuid || '');

  return leafNodes; //.filter(item => item != undefined);
}
//获取:root中定义的颜色值
export function getCpasPrimaryColor() {
  try {
    let color = getComputedStyle(document.documentElement).getPropertyValue('--cpasPrimaryColor').trim();
    if (!color) {
      color = window['main'].mainObject.getWebAppUserConfig().cpasPrimaryColor;
    }
    return color;
  } catch (error) {
    return '';
  }
}

//获取:root中定义的颜色值
export function getCpasPrimaryColor2() {
  try {
    return getComputedStyle(document.documentElement).getPropertyValue('--cpasPrimaryColor2').trim();
  } catch (error) {
    return '';
  }
}
/**
 * 一个'换为两个''
 * @param str
 * @returns
 */
export function replaceQuouteToDbl(str: string) {
  return str ? str.replaceAll("'", "''") : str;
}

/**
 * 自增
 * @param orgValue
 * @param maxLen
 * @param defaultValue
 * @returns
 */
export function strAutoInc(orgValue: string, maxLen: number, defaultValue: string) {
  let result;
  let letterStr;
  let numStr;
  let str;
  let numLen;
  let num;
  let i;
  let A;
  let B;

  i = orgValue.length - 1;
  while (i > 0) {
    str = orgValue.charAt(i);
    if (!/[0-9]/.test(str)) {
      break;
    }
    i--;
  }

  numLen = orgValue.length - i - 1;
  letterStr = orgValue.substring(0, i + 1);
  numStr = orgValue.substring(i + 1);

  if (numStr !== '') {
    if (numLen >= 18) {
      A = numStr.substring(numLen - 18);
      B = numStr.substring(0, numLen - 18);
      num = BigInt(A) + BigInt(1);
      A = num.toString();
      if (A.length < 18) {
        A = '0'.repeat(18 - A.length) + A;
      }
      result = letterStr + B + A;
    } else {
      num = BigInt(numStr) + BigInt(1);
      numStr = num.toString();
      if (numStr.length < numLen) {
        numStr = '0'.repeat(numLen - numStr.length) + numStr;
      }
      result = letterStr + numStr;
    }

    if (maxLen !== 0 && result.length > maxLen) {
      result = defaultValue;
    }
  } else {
    result = defaultValue;
  }

  return result;
}
/**
 *
 * 10位guid
 * @returns
 */
export function nanoid10() {
  return nanoid(10);
}
/**
 * Returns the specified number of characters from the right side of a given string.
 *
 * @param {string} str - The input string from which to extract characters.
 * @param {number} count - The number of characters to retrieve from the right side of the string.
 * @returns {string} A substring containing the specified number of characters from the right side of the input string.
 */
export function rightStr(str: string, count: number) {
  if (typeof str !== 'string' || typeof count !== 'number') {
    throw new Error('Invalid arguments: Expected a string and a number.');
  }

  const maxLength = str.length;
  const effectiveCount = Math.min(maxLength, count);

  return str.slice(-effectiveCount);
}
